package org.sagitta.httprpc.pox.adaptor;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sagitta.httprpc.ResponseMashaller;
import org.sagitta.httprpc.exception.RPCException;
import org.sagitta.httprpc.message.ExceptionResponse;
import org.sagitta.httprpc.message.FaultResponse;
import org.sagitta.httprpc.message.Response;
import org.sagitta.httprpc.pox.message.POXExceptionResponse;
import org.sagitta.httprpc.pox.message.POXFaultResponse;
import org.sagitta.httprpc.pox.message.POXResponse;

class POXResponseMashaller implements ResponseMashaller {
	
	private Marshaller m;
	
	private static final Log log = LogFactory.getLog(POXResponseMashaller.class);
	
	public POXResponseMashaller(JAXBContext context) throws JAXBException {
		m = context.createMarshaller();
	}

	@Override
	public byte[] marshal(Response response) throws RPCException {
		try {
			if (response instanceof ExceptionResponse) {
				response = new POXExceptionResponse((ExceptionResponse)response);
			} else if (response instanceof FaultResponse ) {
				response = new POXFaultResponse((FaultResponse)response);
			} else if (response.getClass().equals(Response.class)) {
				response = POXResponse.getInstance();
			}
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			OutputStream out = new java.io.BufferedOutputStream(bos);
			m.marshal(response, out);
			return bos.toByteArray();
		} catch (JAXBException e) {
			e.printStackTrace();
			throw new RPCException(RPCException.RESPONSEMASHLLERROR);
		}
	} 

	@Override
	public void marshal(Response response, OutputStream stream) throws RPCException {		
		byte[] b = this.marshal(response);
		try {
			if (log.isDebugEnabled()) {
				log.debug("Response: " + new String(b));
			}
			stream.write(b);
		} catch (IOException e) {
			e.printStackTrace();
			throw new RPCException(RPCException.RESPONSEMASHLLERROR);
		}
	}

}
